package com.hurui.xiaoming.weight;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Created by Administrator on 2017/8/2.
 */

public class PaintView extends View {
    private Canvas mCanvas;
    private Path mPath;
    private Paint mBitmapPaint;
    private Bitmap mBitmap;
    private Paint mPaint;

    private ArrayList<DrawPath> savePath;
    private ArrayList<DrawPath> deletePath;

    private List<Float> lineX;
    private List<Float> lineY;
//    private List<Point> listPoint;
//    private List<Point> deletePoint;
    private DrawPath dp;

    private float mX, mY;

    private static final float TOUCH_TOLERANCE = 4;

    private int bitmapWidth;
    private int bitmapHeight;
    private int paintColor = 0xFF000000;
    int p = 0;

    private int a = 1;
    private Point point;
    private boolean isSave;


    public PaintView(Context c) {
        this(c, null);
        //得到屏幕的分辨率
        DisplayMetrics dm = new DisplayMetrics();
        ((Activity) c).getWindowManager().getDefaultDisplay().getMetrics(dm);

        bitmapWidth = dm.widthPixels;
        bitmapHeight = dm.heightPixels - 2 * 45;

    }

    public PaintView(Context c, AttributeSet attrs) {
        super(c, attrs);
        //得到屏幕的分辨率
        DisplayMetrics dm = new DisplayMetrics();
        ((Activity) c).getWindowManager().getDefaultDisplay().getMetrics(dm);

        bitmapWidth = dm.widthPixels;
        bitmapHeight = dm.heightPixels - 2 * 45;

        initCanvas();
        initPaint();


    }

    @Override
    public void setOnFocusChangeListener(OnFocusChangeListener l) {
        super.setOnFocusChangeListener(l);

    }

    //初始化画布
    public void initCanvas() {

        savePath = new ArrayList<>();
        deletePath = new ArrayList<>();
//        listPoint = new ArrayList<>();
//        deletePoint = new ArrayList<>();


    }


    @Override
    protected void onDraw(Canvas canvas) {

        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);     //显示旧的画布
        if (mPath != null) {
            // 实时的显示
            canvas.drawPath(mPath, mPaint);

        }
    }

    //路径对象
    class DrawPath {
        Path path;
        Paint paint;
    }

    public void setPaintColor(int color) {
        this.paintColor = color;
//        initCanvas();
        mPaint.setColor(color);
        invalidate();
    }

    /**
     * 撤销的核心思想就是将画布清空，
     * 将保存下来的Path路径最后一个移除掉，
     * 重新将路径画在画布上面。
     */
    public void undo() {

        if (savePath != null && savePath.size() > 0) {
            //调用初始化画布函数以清空画布
            initPaint();
            //将路径保存列表中的最后一个元素删除 ,并将其保存在路径删除列表中
            DrawPath drawPath = savePath.get(savePath.size() - 1);
            deletePath.add(drawPath);
            savePath.remove(savePath.size() - 1);


            //将路径保存列表中的路径重绘在画布上
            Iterator<DrawPath> iter = savePath.iterator();      //重复保存
            while (iter.hasNext()) {
                DrawPath dp = iter.next();
                mCanvas.drawPath(dp.path, dp.paint);

            }
//            if (listPoint != null && listPoint.size() > 0) {
//                //坐标点需要删除
//                Point point = listPoint.get(listPoint.size() - 1);
//                deletePoint.add(point);
//                listPoint.remove(point);
//            }
            invalidate();// 刷新
        }
    }

    /**
     * 恢复的核心思想就是将撤销的路径保存到另外一个列表里面(栈)，
     * 然后从redo的列表里面取出最顶端对象，
     * 画在画布上面即可
     */
    public void redo() {
        if (deletePath.size() > 0) {
            //将删除的路径列表中的最后一个，也就是最顶端路径取出（栈）,并加入路径保存列表中
            DrawPath dp = deletePath.get(deletePath.size() - 1);
            savePath.add(dp);

            //将取出的路径重绘在画布上
            mCanvas.drawPath(dp.path, dp.paint);
            //将该路径从删除的路径列表中去除
            deletePath.remove(deletePath.size() - 1);
//            if (listPoint != null && listPoint.size() > 0) {
//                //回复点
//                Point point = deletePoint.get(deletePoint.size() - 1);
//                listPoint.add(point);
//                deletePoint.remove(point);
//            }
            invalidate();
        }
    }

    /*
     * 清空的主要思想就是初始化画布
     * 将保存路径的两个List清空
     * */
    public void removeAllPaint() {
        //调用初始化画布函数以清空画布
        initPaint();
        invalidate();//刷新
        savePath.clear();
        deletePath.clear();
//        listPoint.clear();
//        deletePoint.clear();
        lineY.clear();
        lineX.clear();
        a = 1;
        p = 0;

    }


    /**
     * 保存所绘图形
     * 返回绘图文件的存储路径
     *
     * @return
     */
    public Bitmap saveBitmap() {
//        //获得系统当前时间，并以该时间作为文件名
//        String paintPath = "";
//        String str =  "paint.png";
//        File dir = new File("/sdcard/notes/");
//        File file = new File("/sdcard/notes/", str);
//        if (!dir.exists()) {
//            dir.mkdir();
//        } else {
//            if (file.exists()) {
//                file.delete();
//            }
//        }
//
//        try {
//            FileOutputStream out = new FileOutputStream(file);
//            mBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
//            out.flush();
//            out.close();
//            //保存绘图文件路径
//            paintPath = "/sdcard/notes/" + str;
//
//
//        } catch (Exception e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        }
        // 保存绘图为本地图片
        mCanvas.save(Canvas.ALL_SAVE_FLAG);
        mCanvas.restore();
        return mBitmap;
    }


    //手指开始移动
    private void touch_start(float x, float y) {
        mPath.reset();//清空path
        mPath.moveTo(x, y);
        mX = x;
        mY = y;

    }

    //手指移动
    private void touch_move(float x, float y) {
        lineX.add(x);
        lineY.add(y);
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);

        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
            //mPath.quadTo(mX, mY, x, y);
            mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);//源代码是这样写的，可是我没有弄明白，为什么要这样？
            mX = x;
            mY = y;


        }


    }

    //手指抬起
    private void touch_up() {
        lineX.add(mX);
        lineY.add(mY);

        mPath.lineTo(mX, mY);
        mCanvas.drawPath(mPath, mPaint);
        savePath.add(dp);
//        listPoint.add(new Point(lineX, lineY));
        mPath = null;

    }

    /**
     * 初始化画布
     */
    private void initPaint() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(paintColor);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(10);

        mBitmapPaint = new Paint(Paint.DITHER_FLAG);

        //画布大小
        mBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.RGB_565);
        mCanvas = new Canvas(mBitmap);  //所有mCanvas画的东西都被保存在了mBitmap中
        //画布的背景颜色
        mCanvas.drawColor(Color.GRAY);
        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    }

    public void setFoucse() {
        isSave = true;

    }

    /**
     * <p>
     * listPoint最外层集合
     * lineXList x点集合
     * lineyList y点集合
     */
//    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
//    public void recoverPaint() {
//        if (listPoint.size() > 0 && listPoint != null && p < listPoint.size()) {
//            //获得每段的x  y 集合 对象
//            point = listPoint.get(p);
//            //重置画笔  画布
//            mPaint.setColor(Color.BLUE);
//            mPaint.setTextSize(30);
//            mPaint.setUnderlineText(true);
//            mPaint.setElegantTextHeight(true);
//            mPaint.setTypeface(Typeface.SERIF);
//            //获得  x y 集合
//            List<Float> lineXList = point.getlineX();
//            List<Float> lineYList = point.getlineY();
//
//            //画起点、
//            if (p == 0) {
//                mCanvas.drawText("起点", lineXList.get(0), lineYList.get(0), mPaint);
//            }
//            //画终点
//            if (p == listPoint.size() - 1) {
//                mCanvas.drawText("终点", lineXList.get(lineXList.size() - 1), lineYList.get(lineYList.size() - 1), mPaint);
//            }
//            //画图
//            if (a < lineXList.size()) {
//                mCanvas.drawLine(lineXList.get(a - 1), lineYList.get(a - 1), lineXList.get(a), lineYList.get(a), mPaint);
//                a++;
//            } else {
//                p++;
//                a = 1;
//                recoverPaint();
//            }
//        }
//
//
//        invalidate();
//    }


    /**
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                mPath = new Path();
                dp = new DrawPath();
                lineY = new ArrayList<>();
                lineX = new ArrayList<>();
                lineX.add(x);
                lineY.add(y);
                dp.path = mPath;
                dp.paint = mPaint;
                touch_start(x, y);
                Log.e("wlc222", "x: " + x + "===y:" + y);
                invalidate(); //清屏
                break;
            case MotionEvent.ACTION_MOVE:
                touch_move(x, y);
                Log.e("wlc444", "x====: " + x + "    y=====" + y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                touch_up();
                invalidate();
                break;
        }
        return true;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        if (isSave) {
            return false;
        }

        return super.dispatchTouchEvent(event);
    }
}
